package edu.szu.huhanpeng.doodlingFight.model 
{
	import edu.szu.huhanpeng.doodlingFight.globalConst.GlobalConst;
	import edu.szu.huhanpeng.doodlingFight.interfaces.IChessBoardData;
	import edu.szu.huhanpeng.doodlingFight.interfaces.IChessData;
	import edu.szu.huhanpeng.doodlingFight.interfaces.IChessGroupData;
	import flash.utils.Dictionary;
	import org.puremvc.as3.interfaces.INotifier;
	import org.puremvc.as3.interfaces.IProxy;
	import org.puremvc.as3.patterns.proxy.Proxy;
	
	/**
	 * ...
	 * @author Huhanpeng
	 */
	public class ChessGroupProxy extends Proxy implements IProxy, INotifier 
	{
		public static var NAME:String = "ChessGroupProxy";
		
		/////////////////////////////////////////////////////////////////////
		//getter setter                                                    //
		/////////////////////////////////////////////////////////////////////
		
		protected function get groupData():IChessGroupData
		{
			return data as IChessGroupData;
		}
       		
		
		/////////////////////////////////////////////////////////////////////
		//构造函数                                                         //
		/////////////////////////////////////////////////////////////////////
		
		public function ChessGroupProxy(data:IChessGroupData) 
		{
			super(NAME, data);
		}
		
		
		/////////////////////////////////////////////////////////////////////
		//接口                                                             //
		/////////////////////////////////////////////////////////////////////
		/**
		 * 一步移动便可消除的棋子组合在棋盘上的序号
		 * @param	keyChess			要消除的移动棋子data
		 * @param	targetChess			不消除的移动棋子data
		 * @param	...othersChess		其它要消除的棋子data
		 */
		public function addPrepare(keyChess:IChessData, targetChess:IChessData,...othersChess):void
		{
			var vec:Vector.<IChessData> = new <IChessData>[keyChess];
			for (var i:int = 0; i < othersChess.length; i++) 
			{
				if ( othersChess[i] is IChessData ) 
				{
					vec.push(othersChess[i] as IChessData);
				}
				else
				{
					throw new Error("addPrepare剩余参数应为IChessData");
				}
				
			}
			
			if (vec.length < 3) 
			{
				if (GlobalConst.setting.DEBUG) 
				{
					throw new Error("最少要三颗棋子才可以消除");
				}
				else
				{
					return;
				}
			}
			
			//索引功能：作为查询是否能成功的索引，只设置一个有序组，但每次查询时会尝试两个有序组，即chess没有先后区别
			//存储功能：存储成功的情形,存在高星则合并成高星，设置和使用都只用一个有序组，必须keyChess在前
			var idStr:String = getIdStr(keyChess, targetChess);
			if (groupData.index[idStr] != undefined) 
			{	
				var store:Vector.<IChessData> = groupData.index[idStr] as Vector.<IChessData>;
				for (var j:int = 0; j < store.length; j++) 
				{
					vec.push(store[j]);
				}
				
				//去重
				var index:int;
				for (var k:int = 0; k < vec.length; k++) 
				{
					index = vec.lastIndexOf(vec[k]);
					if (index != -1 && index != k) 
					{
						vec.splice(k, 1);
						k--;	//继续检查当前项
					}
				}
			}
			groupData.index[idStr] = vec;
			groupData.moveDic[idStr] = new <IChessData>[keyChess,targetChess];
		}
		
		public function getRobotMove():Vector.<IChessData>
		{
			var best:Vector.<IChessData>;
			var length:int;
			for each( var vec:Vector.<IChessData> in groupData.moveDic )
			{
				if ( best == null || vec.length > length ) 
				{
					best = vec;
					length = vec.length;
				}
			}
			return best;
		}
		
		public function checkSuccess(chessA:IChessData, chessB:IChessData):Boolean 
		{
			if (groupData.index[getIdStr(chessA, chessB)] != undefined || groupData.index[getIdStr(chessB, chessA)] != undefined) 
			{
				return true;
			}			
			else if ( insureCheckSuccess( chessA, chessB ) )
			{
				return true;
			}
			else
			{
				return false;
			}
		}
		
		

		public function resetPrepare():void
		{
			groupData.resetIndex();
			groupData.resetMoveDic();
		}
		
		public function removePrepare(...arg):void 
		{
			var chess:IChessData;
			for (var i:int = 0; i < arg.length; i++) 
			{
				if (!(chess = arg[i] as IChessData)) 
				{
					if (GlobalConst.setting.DEBUG) 
					{
						throw new Error("body类型出错");
					}
					return;
				}
				
				for (var key:String in groupData.index)
				{
					if ( inIdStr(chess, key) )
					{
						delete groupData.index[key];
					}
				}
			}
		}
		
		public function getDone():Array
		{
			return groupData.done;
		}
		
		public function getPrepareDone( chessA:IChessData, chessB:IChessData ):void 
		{
			//if ( !checkSuccess(chessA, chessB) ) 
			//{
				//if (GlobalConst.setting.DEBUG) 
				//{
					//throw new Error("移动该棋子后没有可以消除的组合");
				//}
				//return;
			//}
			
			//index里可能同时有 <chessA, chessB> 和 <chessB, chessA>两种情形
			var idStr:String = getIdStr(chessA, chessB);
			if (groupData.index[idStr] != undefined) 
			{
				groupData.done.push(groupData.index[idStr]);
				delete groupData.index[idStr];
			} 
			//另一序列的idStr
			idStr = getIdStr(chessB, chessA);
			if (groupData.index[idStr] != undefined) 
			{
				groupData.done.push(groupData.index[idStr]);
				delete groupData.index[idStr];
			}
		}
		
		public function resetDone():void
		{
			groupData.resetDone();
		}
		
		public function addDone(doneVec:Vector.<IChessData>):void 
		{
			groupData.done.push( doneVec );
		}
		
		/////////////////////////////////////////////////////////////////////
		//内部                                                             //
		/////////////////////////////////////////////////////////////////////
		
		/**
		* 为两个棋子data组成的有序组创建一个独一的string标识
		* @param	chessA
		* @param	chessB
		* @return	字符串：  标识符MARK + A的名字 + 标识符MARK + B的名字 + 标识符MARK
		*/
		private static const MARK:String = "/*/";
		private function getIdStr(chessA:IChessData, chessB:IChessData):String 
		{
			return MARK.concat( chessA.name.concat(MARK, chessB.name.concat(MARK)) );
		}
		
		/**
		 * 若该棋子为IdStr的组成部分，则返回true
		 * @param	chess
		 * @return
		 */
		private function inIdStr(chess:IChessData, idStr:String ):Boolean
		{
			if ( idStr.indexOf(MARK.concat( chess.name.concat(MARK) ) ) != -1 )
			{
				return true;
			}
			else
			{
				return false;
			}
		}

		//检查是否存在错漏致使在准备列表中缺少成功情况，并弥补此错漏
		private function insureCheckSuccess(chessA:IChessData, chessB:IChessData):Boolean 
		{
			var boolean:Boolean = false;
			var typeA:int = chessA.type;
			var typeB:int = chessB.type;
			
			

			//检查水平方向，若成功则推入成功数组
			checkHorizontal( chessA, chessB );
			checkHorizontal( chessB, chessA );
			//检查垂直方向，若成功则推入成功数组
			checkVertical( chessA, chessB );
			checkVertical( chessB, chessA );
			
			if (groupData.done.length != 0 ) 
			{
				return true;
			}
			else
			{
				return boolean;
			}
		}
		
				
		private function checkVertical(target:IChessData, other:IChessData):Boolean 
		{
			var vec:Vector.<IChessData> = new Vector.<IChessData>();
			var chessT:IChessData;
			
			chessT = (other.square.upSquare != null) ? other.square.upSquare.chessData : null;
			if ( chessT != null && chessT.type == target.type ) 
			{
				if ( chessT != target ) 
				{
					vec.push( chessT );
				}
				chessT = (chessT.square.upSquare != null) ? chessT.square.upSquare.chessData : null;
				if ( chessT != null && chessT.type == target.type ) 
				{
					vec.push( chessT );
				}
			}
			
			vec.push( target );
			
			chessT = (other.square.downSquare != null) ? other.square.downSquare.chessData : null;
			if ( chessT != null && chessT.type == target.type ) 
			{
				if ( chessT != target ) 
				{
					vec.push( chessT );
				}
				chessT = (chessT.square.downSquare != null) ? chessT.square.downSquare.chessData : null;
				if ( chessT != null && chessT.type == target.type ) 
				{
					vec.push( chessT );
				}
			}
			
			if ( vec.length > 2) 
			{
				groupData.done.push( vec );
				return true;
			}
			else
			{
				return false;
			}
			
		}
		
		private function checkHorizontal(target:IChessData, other:IChessData):Boolean 
		{
			var vec:Vector.<IChessData> = new Vector.<IChessData>();
			var chessT:IChessData;
			
			chessT = (other.square.leftSquare != null) ? other.square.leftSquare.chessData : null;
			if ( chessT != null && chessT.type == target.type ) 
			{
				if ( chessT != target ) 
				{
					vec.push( chessT );
				}
				chessT = (chessT.square.leftSquare != null) ? chessT.square.leftSquare.chessData : null;
				if ( chessT != null && chessT.type == target.type ) 
				{
					vec.push( chessT );
				}
			}
			
			vec.push( target );
			
			chessT = (other.square.rightSquare != null) ? other.square.rightSquare.chessData : null;
			if ( chessT != null && chessT.type == target.type ) 
			{
				if ( chessT != target ) 
				{
					vec.push( chessT );
				}
				chessT = (chessT.square.rightSquare != null) ? chessT.square.rightSquare.chessData : null;
				if ( chessT != null && chessT.type == target.type ) 
				{
					vec.push( chessT );
				}
			}
			
			if ( vec.length > 2) 
			{
				groupData.done.push( vec );
				return true;
			}
			else
			{
				return false;
			}
			
		}
	}

}